package org.example;

import com.alibaba.fastjson.JSON;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author liukaihao
 * @date 2025/03/03
 */
public class Main92 {
    public static void main(String[] args) {
        List<Book> books = new ArrayList<>();

        Book book1 = new Book("1","程序员的自我修养1","大卫1","图灵出版社1");
        Book book2 = new Book("2","程序员的自我修养2","大卫2","图灵出版社2");
        Book book3 = new Book("3","程序员的自我修养3","大卫3","图灵出版社3");
        Book book4 = new Book("4","程序员的自我修养4","大卫4","图灵出版社4");
        Book book5 = new Book("5","程序员的自我修养5","大卫5","图灵出版社5");
        Book book6 = new Book("6","程序员的自我修养5","大卫5","图灵出版社5");

        books.add(book1);
        books.add(book2);
        books.add(book3);
        books.add(book4);
        books.add(book5);
        books.add(book6);
        //3:将图书列表转换为Set<Book>，去除重复的图书记录（假设图书的唯一标识是其标题和作者）
        Set<Book> set = new HashSet<>();
        // 零时使用的变量，作为key的判断
        HashMap<String, String> map = new HashMap<>();
        for (Book book : books) {
            String key = book.getTitle()+book.getAuthor();
            if(!map.containsKey(key)) {
                map.put(key,"1");
                set.add(book);
            }
        }
        System.out.println("第三题："+ JSON.toJSONString(set));
        //4：使用Map<String, Book>存储图书信息，其中键为图书标题，值为Book对象
        Map<String,Book> map4 = new HashMap<>();
        for (Book book : books) {
            String key = book.getTitle();
            map4.put(key,book);
        }
        System.out.println("第4题："+JSON.toJSONString(map4));

        //6.使用线程安全的集合类（如CopyOnWriteArrayList或Collections.synchronizedList）创建一个线程安全的图书列表
        List<Book> syncList = Collections.synchronizedList(books);
        System.out.println("第6题："+JSON.toJSONString(syncList));


        //7.¢创建多个线程模拟同时向图书列表中添加新的图书记录。
        //确保在并发修改过程中不会出现数据不一致的问题
        test7(syncList);



        //8.¢创建多个线程模拟同时从图书列表中读取图书信息。
        //确保读取操作不会受到写入操作的影响
        test8(syncList);

        //9.在图书列表的增删操作中使用synchronized关键字确保线程安全
        syncAddBooks9(books);
        syncDelBooks9(books);

        //10.使用ReentrantLock或其他Lock实现类替代synchronized关键字，实现对图书列表的细粒度锁管理
        test10(books);





    }

    public  static void test10(List<Book> books){
        ReentrantLock lock = new ReentrantLock();
        for(int i=0;i<3;i++){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    lock.lock();
                    try {
                        books.stream().forEach(book -> {
                            System.out.println(JSON.toJSONString(book));
                        });
                        //业务逻辑
                    }catch (Exception e) {
                        lock.unlock();
                    }
                    //业务逻辑
                }
            });
        }
    }




    public static synchronized List<Book>  syncAddBooks9(List<Book> books){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Book book9 = new Book("9","程序员的自我修养9","大卫9","图灵出版社9");
                books.add(book9);
            }
        });
        return books;
    }
    public static synchronized List<Book>  syncDelBooks9(List<Book> books){
        new Thread(new Runnable() {
            @Override
            public void run() {
                books.remove(1);
            }
        });
        return books;
    }




    /*public  static void addTest92(List<Book> books){
        for(int i=0;i<3;i++){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    addTest9(books);
                }
            });
            thread.start();
        }
    }
    *//***
     * synchronized 被这个关键字修饰后这个方法就是线程安全
     * @param books
     * @return
     *//*
    public static synchronized List<Book> addTest9(List<Book> books){
        Book book9 = new Book("9","程序员的自我修养9","大卫9","图灵出版社9");
        books.add(book9);
        System.out.println("------>");
        //业务逻辑
        return books;
    }



    public  static void delTest92(List<Book> books){
        for(int i=0;i<3;i++){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    delTest9(books);
                }
            });
        }
    }
    public static synchronized List<Book> delTest9(List<Book> books){
        books.remove(1);
        return books;
    }*/




    public static List<Book> test5(List<Book> books,String title){
        List<Book> list = new ArrayList<>();
        for(Book book : books){
            if(book.getTitle().equals(title)){
                list.add(book);
            }
        }
        return list;
    }

    public static List<Book> test7(List<Book> books){

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Book book7 = new Book("7","程序员的自我修养7","大卫7","图灵出版社7");
                books.add(book7);
                System.out.println("test7 1:"+Thread.currentThread().getName()+";size="+books.size());
            }
        });
        thread1.start();

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Book book8 = new Book("8","程序员的自我修养8","大卫8","图灵出版社8");
                books.add(book8);
                System.out.println("test7 2:"+Thread.currentThread().getName()+";size="+books.size());
            }
        });
        thread2.start();

        return books;
    }


    public static List<Book> test8(List<Book> books){
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for(int i=0;i<5;i++) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    books.stream().forEach(book -> {
                        System.out.println(Thread.currentThread().getName()+":"+JSON.toJSONString(book));
                    });
                }
            });
        }

        executorService.shutdownNow();
        return books;
    }




}
